unit time;

interface
uses CoreI;
Function Core_GetTime:Int64; cdecl;
Function Core_AddTimer(const interval:cardinal; TimerProc:TTimerProc; data:pointer):TTimerID; cdecl;
procedure Core_RemoveTimer(const timer:TTimerID); cdecl;
procedure Time_Update;
var CoreTime:int64=0;
implementation
uses sdl, lists;
type PTimerListNode = ^TTimerListNode;
TTimerListNode=record
interval:integer;
elapsed:integer;
proc:TTimerProc;
data:pointer;
ID:TTimerID;
end;
var MaxTimerID:cardinal;
timers:PList;
LastTick:int64;
Function Core_GetTime:Int64; cdecl;
begin
result:=CoreTime;
end;

Function Core_AddTimer(const interval:cardinal; TimerProc:TTimerProc; data:pointer):TTimerID; cdecl;
var t:PTimerListNode;
begin
new(t);
t^.interval := interval;
t^.elapsed := interval;
t^.proc := TimerProc;
t^.data := data;
inc(MaxTimerID);
t^.ID := MaxTimerID;
list_add(Timers, t);
result := MaxTimerID;
end;

procedure Core_RemoveTimer(const timer:TTimerID); cdecl;
var PWalk: PList;
begin
         PWalk := Timers;
         while PWalk <> nil do begin
if PTimerListNode(PWalk^.Data)^.ID = Timer then begin
dispose(PTimerListNode(PWalk^.Data));
list_removenode(timers, PWalk);
break;
end;
         PWalk := PWalk^.Next;
         end;
end;

procedure Time_Update;
var Tick:Int64;
TicksElapsed:integer;
PWalk,PNext: PList;
i:integer;
t:PTimerListNode;
begin
tick := sdl_GetTicks();
TicksElapsed:=Tick - LastTick;
LastTick := tick;
if core_getstate <> core_running then exit;
inc(CoreTime, TicksElapsed);

PWalk := Timers;
while PWalk <> nil do begin
PNext := PWalk^.Next;
                 t:=PWalk^.Data;
                 dec(t^.elapsed, ticksElapsed);
                 if t^.elapsed <= 0 then begin
i:= t^.proc(t^.ID, t^.data);
if i = -1 then begin
                     dispose(t);
                     list_removenode(Timers, PWalk);
                     end else begin
if i >0 then t^.interval := i;
t^.elapsed := t^.interval;
end;
                 end;
                 PWalk := PNext;
end;
                            end;
end.
